package com.dy.lock.screen.service.impl;

import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.dy.lock.screen.constants.Constant;
import com.dy.lock.screen.dao.AdvertOperatorDao;
import com.dy.lock.screen.pojo.AdvertCollectInfo;
import com.dy.lock.screen.pojo.AdvertInfo;
import com.dy.lock.screen.pojo.AdvertOperatorInfo;
import com.dy.lock.screen.pojo.ScoreInfo;
import com.dy.lock.screen.pojo.UserInfo;
import com.dy.lock.screen.scoket.Head;
import com.dy.lock.screen.service.AdvertCollectService;
import com.dy.lock.screen.service.AdvertOperatorService;
import com.dy.lock.screen.service.AdvertService;
import com.dy.lock.screen.service.ScoreService;
import com.dy.lock.screen.service.UserService;
import com.dy.lock.screen.utils.CommonUtil;
import com.dy.lock.screen.vo.AdvertOperateTypeVo;

@Service("advertOperatorService")
public class AdvertOperatorServiceImpl implements AdvertOperatorService {

	private static final Logger log = Logger
			.getLogger(AdvertOperatorServiceImpl.class);

	@Resource(name = "advertOperatorDao")
	private AdvertOperatorDao advertOperatorDao;
	@Resource(name = "advertCollectService")
	private AdvertCollectService advertCollectService;
	@Resource(name = "scoreService")
	private ScoreService scoreService;
	@Resource(name = "userService")
	private UserService userService;
	@Resource(name = "advertService")
	private AdvertService advertService;

	@Override
	public int save(AdvertOperatorInfo operatorInfo, Head head) {
		operatorInfo.setId(UUID.randomUUID().toString());
		operatorInfo.setOperatorTime(new Date());
		return this.advertOperatorDao.insert(operatorInfo);
	}

	@Override
	public int saveBatch(List<AdvertOperateTypeVo> adOpType, String userId,
			Head head) throws Exception {
		int re = 0;
		try {
			if (adOpType != null && !adOpType.isEmpty()) {
				for (AdvertOperateTypeVo opt : adOpType) {
					AdvertOperatorInfo adOpt = new AdvertOperatorInfo();
					adOpt.setAdId(opt.getAdId());
					adOpt.setUserId(userId);
					adOpt.setAdScore(opt.getScore());
					adOpt.setOperatorType(opt.getAdOptType());
					this.updateCalDisplayOrClickTimes(opt, head);
					this.save(adOpt, head);
					if (Constant.ADVERT_OPERATE_COLLECT.equals(opt
							.getAdOptType())) { // 收藏广告
						AdvertCollectInfo collDb = this.advertCollectService
								.queryByAdAndUser(opt.getAdId(), userId, head);
						if (collDb == null) {
							AdvertCollectInfo co = new AdvertCollectInfo();
							co.setAdId(opt.getAdId());
							co.setUserId(userId);
							this.advertCollectService.save(co, head);
						}

					}
					if (Constant.ADVERT_OPERATE_CANCEL_COLLECT.equals(opt
							.getAdOptType())) { // 取消收藏
						this.advertCollectService.delete(opt.getAdId(), userId,
								head);
					}
					if (Constant.ADVERT_OPERATE_LEFT.equals(opt.getAdOptType())
							|| Constant.ADVERT_OPERATE_RIGHT.equals(opt
									.getAdOptType())) {
						re = this.saveOrUpdateScore(userId, opt.getAdOptType(),
								opt.getScore(), head);
					}

				}
				re = 1;
			}
		} catch (Exception e) {
			log.error("requestId:" + head.getRequestId() + ",保存广告操作记录时，出现异常。",
					e);
			throw e;
		}
		return re;
	}

	/**
	 * 计算已点击，已展示，已付费展示次数，更新投放状态，投放结束时间
	 * 
	 * @param opt
	 * @return
	 */
	private int updateCalDisplayOrClickTimes(AdvertOperateTypeVo opt, Head head) {
		String adId = opt.getAdId();
		int re = 0;
		AdvertInfo adInfo = this.advertService.queryByPrimaryKey(adId, head);
		if (adInfo != null) {
			Integer totalTimes = adInfo.getTotalTimes();
			Integer clicked = adInfo.getClickedTimes();
			Integer displayed = adInfo.getDisplayedTimes();
			Integer payDisplayed = adInfo.getPayDisplayTimes();
			AdvertInfo ad = new AdvertInfo();
			ad.setAdId(adId);
			if (Constant.ADVERT_CPM.equals(adInfo.getAdType())
					&& !CommonUtil.compare(displayed, totalTimes)) {
				if (opt.getScore() > 0
						&& Constant.ADVERT_OPERATE_RIGHT.equals(opt
								.getAdOptType())) {
					payDisplayed = CommonUtil.add(payDisplayed, 1);
				}
				if (Constant.ADVERT_OPERATE_LOOK.equals(opt.getAdOptType())) {
					displayed = CommonUtil.add(displayed, 1);
				}
				ad.setDisplayedTimes(displayed);
				ad.setPayDisplayTimes(payDisplayed);
				re = this.advertService.update(ad, head);
			} else if (Constant.ADVERT_CPC.equals(adInfo.getAdType())
					&& !CommonUtil.compare(clicked, totalTimes)) {
				clicked = CommonUtil.add(clicked, 1);
				ad.setClickedTimes(clicked);
				re = this.advertService.update(ad, head);
			} else {
				ad.setStatus(Constant.ADVERT_STATUS_END);
				ad.setEndTime(new Date());
				re = this.advertService.update(ad, head);
			}
		}

		return re;
	}

	/**
	 * 增加左滑右滑积分
	 * 
	 * @param userId
	 * @param adType
	 * @param adScore
	 * @param head
	 * @return
	 */
	private int saveOrUpdateScore(String userId, String adType, int adScore,
			Head head) {
		int re = -1;
		ScoreInfo sc = this.scoreService.queryByPrimaryKey(userId);
		UserInfo u = this.userService.queryByPrimaryKey(userId, head);
		ScoreInfo scIn = new ScoreInfo();
		scIn.setCustomerId(userId);
		scIn.setCustomerName(u.getUserName());
		if (sc == null) {
			if (Constant.ADVERT_OPERATE_LEFT.equals(adType)) {
				scIn.setLeftSlideScore(adScore);
			}
			if (Constant.ADVERT_OPERATE_RIGHT.equals(adType)) {
				scIn.setRightSlideScore(adScore);
			}
			scIn.setExchangedScore(adScore);
			scIn.setTotalScore(adScore);
			scIn.setInsertTime(new Date());
			re = this.scoreService.save(scIn);
		} else {
			if (Constant.ADVERT_OPERATE_LEFT.equals(adType)) {
				scIn.setLeftSlideScore(CommonUtil.add(sc.getLeftSlideScore(),
						adScore));
			}
			if (Constant.ADVERT_OPERATE_RIGHT.equals(adType)) {
				scIn.setRightSlideScore(CommonUtil.add(sc.getRightSlideScore(),
						adScore));
			}
			scIn.setExchangedScore(CommonUtil.add(sc.getExchangedScore(),
					adScore));
			scIn.setTotalScore(CommonUtil.add(sc.getTotalScore(), adScore));
			scIn.setUpdateTime(new Date());
			re = this.scoreService.updateScore(scIn);
		}

		return re;
	}

	@Override
	public List<AdvertOperatorInfo> queryByCustomerId(AdvertOperatorInfo info) {
		// TODO Auto-generated method stub
		return this.advertOperatorDao.queryByCustomerId(info);
	}
}
